package com.cw.lang.common.framework.converter;

import java.util.List;

import com.cw.base.common.model.dto.base.BaseRequest;
import com.cw.base.common.model.enums.EnumModuleCode;
import com.cw.base.common.model.enums.EnumServiceScene;
import com.cw.lang.common.constants.SymbolConstants;
import com.cw.lang.common.utils.DateUtil;
import com.cw.lang.common.utils.StringUtil;
import com.google.common.base.Splitter;

/**
 * @author chenw
 * @version $$Id: BaseRequestConverter.java, v 0.1 2018/11/1 5:01 PM chenw Exp $$
 */
public class BaseRequestConverter {
    /**
     * 请求模块
     */
    private static final String ASK = "ask";
    /**
     * 响应模块
     */
    private static final String ANSWER = "answer";
    /**
     * 统一渠道流水号
     */
    private static final String SERIAL_NO = "serialNo";
    /**
     * 幂等流水号（默认可以使用统一的统一渠道流水号）
     */
    private static final String IDEM_SERIAL_NO = "idemSerialNo";
    /**
     * 服务场景
     */
    private static final String SERVICE_SCENE = "serviceScene";
    /**
     * 交易日期时间
     */
    private static final String TRANS_DATE_TIME = "transDateTime";
    /**
     * 渠道标示 (需要渠道管理动态配置）
     */
    private static final String CHANNEL_NO = "channelNo";
    /**
     * 签名-UUID 用于系统发放的TOKEN验证，比如管理台发放的TOKEN、门户发放的TOKEN、APP发放的TOKEN，原则粒度是在租户下的渠道支持控制
     */
    private static final String SIGN = "sign";

    /**
     * 把对象转为uri结构
     *
     * @param baseRequest {@link BaseRequest}
     * @return uri结构字符串
     */
    public static String encode(BaseRequest baseRequest) {
        if (baseRequest == null) {
            return StringUtil.EMPTY;
        }
        StringBuilder sb = new StringBuilder();
        if (baseRequest.getAsk() != null) {
            sb.append(ASK)
                .append(SymbolConstants.EQUAL)
                .append(baseRequest.getAsk()
                    .getCode())
                .append(SymbolConstants.AND);
        }
        if (baseRequest.getAnswer() != null) {
            sb.append(ANSWER)
                .append(SymbolConstants.EQUAL)
                .append(baseRequest.getAnswer()
                    .getCode())
                .append(SymbolConstants.AND);
        }
        if (StringUtil.isNotBlank(baseRequest.getSerialNo())) {
            sb.append(SERIAL_NO)
                .append(SymbolConstants.EQUAL)
                .append(baseRequest.getSerialNo())
                .append(SymbolConstants.AND);
        }
        if (StringUtil.isNotBlank(baseRequest.getIdemSerialNo())) {
            sb.append(IDEM_SERIAL_NO)
                .append(SymbolConstants.EQUAL)
                .append(baseRequest.getIdemSerialNo())
                .append(SymbolConstants.AND);
        }
        if (baseRequest.getServiceScene() != null) {
            sb.append(SERVICE_SCENE)
                .append(SymbolConstants.EQUAL)
                .append(baseRequest.getServiceScene()
                    .getCode())
                .append(SymbolConstants.AND);
        }
        if (baseRequest.getTransDateTime() != null) {
            sb.append(TRANS_DATE_TIME)
                .append(SymbolConstants.EQUAL)
                .append(DateUtil.date2String(baseRequest.getTransDateTime(), DateUtil.DATETIME_FORMAT_2))
                .append(SymbolConstants.AND);
        }
        if (StringUtil.isNotBlank(baseRequest.getChannelNo())) {
            sb.append(CHANNEL_NO)
                .append(SymbolConstants.EQUAL)
                .append(baseRequest.getChannelNo())
                .append(SymbolConstants.AND);
        }
        if (StringUtil.isNotBlank(baseRequest.getSign())) {
            sb.append(SIGN)
                .append(SymbolConstants.EQUAL)
                .append(baseRequest.getSign())
                .append(SymbolConstants.AND);
        }
        return sb.length() == 0 ? StringUtil.EMPTY : sb.substring(0, sb.length() - 1);
    }

    /**
     * 把uri结构字符串转为{@link BaseRequest}
     *
     * @param uriStr uri结构字符串
     * @return 转换后的对象
     */
    public static BaseRequest decode(String uriStr) {
        if (StringUtil.isBlank(uriStr)) {
            return null;
        }
        BaseRequest.Builder builder = BaseRequest.Builder.getInstance();
        List<String> parameterList = Splitter.on(SymbolConstants.AND)
            .splitToList(uriStr);
        for (String parameter : parameterList) {
            List<String> nameValueParameter = Splitter.on(SymbolConstants.EQUAL)
                .splitToList(parameter);
            if (ASK.equals(nameValueParameter.get(0))) {
                builder.addAsk(EnumModuleCode.find(nameValueParameter.get(1)));
            }
            if (ANSWER.equals(nameValueParameter.get(0))) {
                builder.addAnswer(EnumModuleCode.find(nameValueParameter.get(1)));
            }
            if (SERIAL_NO.equals(nameValueParameter.get(0))) {
                builder.addSerialNo(nameValueParameter.get(1));
            }
            if (IDEM_SERIAL_NO.equals(nameValueParameter.get(0))) {
                builder.addIdemSerialNo(nameValueParameter.get(1));
            }
            if (SERVICE_SCENE.equals(nameValueParameter.get(0))) {
                builder.addServiceScene(EnumServiceScene.find(nameValueParameter.get(1)));
            }
            if (TRANS_DATE_TIME.equals(nameValueParameter.get(0))) {
                builder.addTransDateTime(DateUtil.string2Date(nameValueParameter.get(1)));
            }
            if (CHANNEL_NO.equals(nameValueParameter.get(0))) {
                builder.addChannelNo(nameValueParameter.get(1));
            }
            if (SIGN.equals(nameValueParameter.get(0))) {
                builder.addSign(nameValueParameter.get(1));
            }
        }
        return builder.build();
    }
}
